//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Habitacion.h" 
//---------------------------------------------------------------------------

#pragma package(smart_init)
Habitacion::Habitacion(){
    Objeto3D * paredv, *paredp, *suelo, *paredpmas;
    ObjetoCompuesto3D * muebles;
    int alto = 100;
    int ancho = 100;
    int grosor = 5;
    Lista <PV> * vertices;
    poligonos= new Lista<Poligono>();

    //Persiana
    Persiana * persiana=new Persiana(.5,2.*ancho/3.,grosor/2,alto/(3.*2.5)+1,2);
    blind=persiana;
    persiana->color->set(.3,.9,.2);
    objetos->anadir(persiana);
    PV * p= new PV(0,1,0,0);
    persiana->marco_de_coordenadas->rotate(-90,p);
    delete p;
    p= new PV(2.*ancho/3.,alto/3.,-grosor-2,0);
    persiana->marco_de_coordenadas->traslate(p);
    delete p;

    //Pared con hueco para empotrar una ventana
    paredv = new ParedVentana(ancho*2, alto, grosor);
    p= new PV(0,1,0,0);
    paredv->marco_de_coordenadas->rotate(-90,p);
    delete p;
    paredv->color->set(.8,.8,.8);
    objetos->anadir(paredv);
    vertices=new Lista<PV>();
    vertices->anadir(new PV(0,0,0,1));
    vertices->anadir(new PV(0,0,ancho*2,1));
    vertices->anadir(new PV(-grosor,0,ancho*2,1));
    vertices->anadir(new PV(-grosor,0,0,1));
    Convexo *c=new Convexo(vertices);
    poligonos->anadir(c);




    //Pared con hueco para empotrar una puerta
    paredp=new ParedPuerta(ancho, alto, grosor);
    paredp->color->set(.8,.8,.8);
    p= new PV(0,0,0,0);
    paredp->marco_de_coordenadas->traslate(p);
    delete p;

    objetos->anadir(paredp);
    vertices=new Lista<PV>();
    vertices->anadir(new PV(0,0,0,1));
    vertices->anadir(new PV(0,0,-grosor,1));
    vertices->anadir(new PV(ancho/3,0,-grosor,1));
    vertices->anadir(new PV(ancho/3,0,0,1));
    c=new Convexo(vertices);
    poligonos->anadir(c);

    vertices=new Lista<PV>();
    vertices->anadir(new PV(ancho*2/3,0,0,1));
    vertices->anadir(new PV(ancho*2/3,0,-grosor,1));
    vertices->anadir(new PV(ancho,0,-grosor,1));
    vertices->anadir(new PV(ancho,0,0,1));
    c=new Convexo(vertices);
    poligonos->anadir(c);    

    //Pared pa rellenar, pa alargarla vamos
    paredpmas = new Tablero(50,alto,grosor,7,7,2);
    paredpmas->color->set(.8,.8,.8);
    p= new PV(1,0,0,0);
    paredpmas->marco_de_coordenadas->rotate(-90,p);
    delete p;
    p= new PV(ancho,0,0,0);
    paredpmas->marco_de_coordenadas->traslate(p);
    delete p;
    objetos->anadir(paredpmas);
    vertices=new Lista<PV>();
    vertices->anadir(new PV(0,0,0,1));
    vertices->anadir(new PV(0,0,-grosor,1));
    vertices->anadir(new PV(50,0,-grosor,1));
    vertices->anadir(new PV(50,0,0,1));
    c=new Convexo(vertices);
    poligonos->anadir(c);

    //suelo estilo tablero de ajedrez
    suelo=new Suelo(ancho*1.5, ancho*2, grosor,6);
    p= new PV(1,0,0,0);
    suelo->marco_de_coordenadas->rotate(90,p);
    delete p;
    objetos->anadir(suelo);

    //Mesa
    GLfloat altura, anchura, longitud,radio,gros;
    altura = alto/5.;
    anchura = ancho/2.;
    longitud = ancho/3.5;
    radio = 4;
    gros = 2;
    Mesa * mesa = new Mesa(altura,anchura,longitud,gros,radio);
    p= new PV(1,0,0,0);
    mesa->marco_de_coordenadas->rotate(270,p);
    delete p;
    objetos->anadir(mesa);
    p= new PV(60,-85,5,0);
    mesa->marco_de_coordenadas->traslate(p);
    delete p;
    mesa->color->set(.6,.2,.1);
    afin_mesa = mesa->marco_de_coordenadas;
    vertices=new Lista<PV>();
    PV * s=new PV(0,0,0,1);
    s=mesa->marco_de_coordenadas->postMulVector(s);
    vertices->anadir(s);
     s=new PV(0,longitud,0,1);
    s=mesa->marco_de_coordenadas->postMulVector(s);
    vertices->anadir(s);
     s=new PV(anchura,longitud,0,1);
    s=mesa->marco_de_coordenadas->postMulVector(s);
    vertices->anadir(s);
     s=new PV(anchura,0,0,1);
    s=mesa->marco_de_coordenadas->postMulVector(s);
    vertices->anadir(s);
    c=new Convexo(vertices);
    poligonos->anadir(c);

    //Puerta
    Puerta * puerta = new Puerta(2*alto/3., ancho/3.,grosor);
    door=puerta;
    puerta->color->set(.6,.2,.1,1);
    objetos->anadir(puerta);
    p= new PV(1,0,0,0);
    puerta->marco_de_coordenadas->rotate(270,p);
    delete p;
    p= new PV(0,1,0,0);
    puerta->marco_de_coordenadas->rotate(270,p);
    delete p;
    p= new PV(0,0,-ancho/3.*2.,0);
    puerta->marco_de_coordenadas->traslate(p);
    delete p;


    vertices=new Lista<PV>();
    s=new PV(0,0,0,1);
    s=puerta->marco_de_coordenadas->postMulVector(s);
    s->setY(0);
    
    vertices->anadir(s);
     s=new PV(0,0,ancho/3,1);
    s=puerta->marco_de_coordenadas->postMulVector(s);
    s->setY(0);

    vertices->anadir(s);
    s=new PV(0,grosor,ancho/3,1);
    s=puerta->marco_de_coordenadas->postMulVector(s);
    s->setY(0);

    vertices->anadir(s);
    s=new PV(0,grosor,0,1);
    s=puerta->marco_de_coordenadas->postMulVector(s);
    s->setY(0);


    vertices->anadir(s);
    c=new Convexo(vertices);
    poligonos->anadir(c);
    puerta->setArea(poligonos->getLongitud());

    //Estanteria
    int numEst=4;
    Estanteria * estanteria=new Estanteria(grosor/3.,ancho/3.-10,grosor+3,numEst,alto/(3.*numEst));
    estanteria->color->set(.6,.2,.1,1);
    objetos->anadir(estanteria);
    p= new PV(10+2*ancho/3.,alto/3.,0,0);
    estanteria->marco_de_coordenadas->traslate(p);
    delete p;
    afin_estanteria = estanteria->marco_de_coordenadas;

    //Lampara
    Lampara *lampara =new Lampara(2*alto/3,radio,radio*2,10,10);
    objetos->anadir(lampara);
    p= new PV(1,0,0,0);
    lampara->marco_de_coordenadas->rotate(-90,p);
    delete p;
    p= new PV(ancho/5.,-10,grosor,0);
    lampara->marco_de_coordenadas->traslate(p);
    delete p;
    afin_lampara = lampara->marco_de_coordenadas;
    vertices=new Lista<PV>();
    s=new PV(0,0,0,1);
    s=lampara->marco_de_coordenadas->postMulVector(s);
    s->setY(0);
    vertices->anadir(s);
    s=new PV(radio,0,0,1);
    s=lampara->marco_de_coordenadas->postMulVector(s);
    s->setY(0);
    vertices->anadir(s);
     s=new PV(radio,-radio,0,1);
    s=lampara->marco_de_coordenadas->postMulVector(s);
    s->setY(0);
    vertices->anadir(s);
     s=new PV(0,-radio,0,1);
    s=lampara->marco_de_coordenadas->postMulVector(s);
    s->setY(0);
    vertices->anadir(s);
    c=new Convexo(vertices);
    poligonos->anadir(c);

    //Persona
    GLfloat radC=5;
    GLfloat radB=1.5;
    GLfloat radP=2;
    Persona *persona=new Persona(2*alto/3-20,radC,4*radP,2*radP+2,radP,radB,5,5);
    person=persona;
    objetos->anadir(persona);
    p = new PV(1,0,0,0);
    persona->marco_de_coordenadas->rotate(-90,p);
    delete p;
    p = new PV(0,0,1,0);
    persona->marco_de_coordenadas->rotate(90,p);
    delete p;
    p= new PV(-4*ancho/5.,-2*grosor,grosor+radP/1.5,0);
    persona->marco_de_coordenadas->traslate(p);
    delete p;
    afin_gepeto = persona->marco_de_coordenadas;

    PV * pos= new PV(0,0,0,1);
    pos=person->marco_de_coordenadas->postMulVector(pos);
    pos->setY(0);
    PV * sen=new PV(0,-1,0,0);
    sen=person->marco_de_coordenadas->postMulVector(sen);
    sen->setY(0);
    pelota=new Pelota(pos,sen,1.6*radC);


    //Tierra colgante
    Tierra * tierra = new Tierra(10,15,15);
    objetos->anadir(tierra);
    afin_tierra = tierra->marco_de_coordenadas;
        //posicionandola
         p= new PV(125,70,20,0);
        tierra->marco_de_coordenadas->traslate(p);
        delete p;
        p= new PV(1,0,0,0);
        tierra->marco_de_coordenadas->rotate(90,p);
        delete p;


        //hilo que la sujeta (juas)
        Cilindro *ci = new Cilindro(.5,.5,30,8,8);
        objetos->anadir(ci);
        p= new PV(125,70,20,0);
        ci->marco_de_coordenadas->traslate(p);
        delete p;
        p= new PV(1,0,0,0);
        ci->marco_de_coordenadas->rotate(-90,p);
        delete p;


}

void Habitacion::cerrarPuerta(GLfloat angulo){
        int ancho = 100;
        int grosor = 5;

        PV * p= new PV(1,0,0,0);
        door->marco_de_coordenadas->rotate(angulo,p);
        delete p;
        
        Lista <PV> *vertices=new Lista<PV>();
        PV *s=new PV(0,0,0,1);
        s=door->marco_de_coordenadas->postMulVector(s);
        s->setY(0);
        vertices->anadir(s);
        s=new PV(0,0,ancho/3,1);
        s=door->marco_de_coordenadas->postMulVector(s);
        s->setY(0);
        vertices->anadir(s);
        s=new PV(0,grosor,ancho/3,1);
        s=door->marco_de_coordenadas->postMulVector(s);
        s->setY(0);
        vertices->anadir(s);
        s=new PV(0,grosor,0,1);
        s=door->marco_de_coordenadas->postMulVector(s);
        s->setY(0);
        vertices->anadir(s);
        //delete poligonos->dameDato(door->getArea());
        //poligonos->setDato(door->getArea(),new Convexo(vertices));
        //poligonos->eliminaDato(door->getArea());
        Convexo *c=new Convexo(vertices);
        delete poligonos->dameDato(door->getArea())->vertices;
        poligonos->dameDato(door->getArea())->vertices=c->vertices;
        delete ((Convexo*)poligonos->dameDato(door->getArea()))->normales;
        ((Convexo*)poligonos->dameDato(door->getArea()))->normales=c->normales;
        //Convexo *c=new Convexo(vertices);
       // poligonos->anadir(c);
       // door->setArea(poligonos->getLongitud());
}

void Habitacion::muevePersona(PV* dir){
//se mueve en el plano -x,-y
    person->muevePersona(dir);
    PV * pos= new PV(0,0,0,1);
    delete pelota->posicion;
    pelota->posicion=person->marco_de_coordenadas->postMulVector(pos);
    pelota->posicion->setY(0);
    if(choque(dir)){
            dir->escalacion(-1);
          person->muevePersona(dir);

    }

}

void Habitacion::rotaPersona(GLfloat angulo){
//se mueve en el plano -x,-y
        person->rotaPersona(angulo);
        PV * sen=new PV(0,-1,0,0);
        delete pelota->sentido;
        pelota->sentido=person->marco_de_coordenadas->postMulVector(sen);
        pelota->sentido->setY(0);
}

bool Habitacion::choque(PV * dir){

    bool choque = false;

    PV *normal = pelota->sentido->copiar();
    GLdouble tIn = 1;
    double signo=1;
    if(dir->getY()>0)  signo=-1;

    pelota->sentido->escalacion(signo);

    for(int i=1; i <= poligonos->dameNumNodos() && !choque;i++){

        Poligono * k= poligonos->dameDato(i);

        if(k->colision(pelota->posicion, pelota->sentido, pelota->radio, tIn, normal)){
                choque = true;

        }
    }
    pelota->sentido->escalacion(signo);
    return choque;


}
void Habitacion::desplazarObjetos(TAfin *obj,PV* desp){
         obj->traslate(desp);
         
}
void Habitacion::rotarObjetos(TAfin *obj,PV * rot){

          obj->rotate(5,rot);

}
void Habitacion::escalarObjetos(TAfin *obj, PV* sc){
         obj->scale(sc->getX(),sc->getY(),sc->getZ());
}




